home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / tex / xtexcad-.000 / xtexcad- / orig_src / file_sel.c < prev    next >
C/C++ Source or Header  |  1993-03-04  |  37KB  |  868 lines

  1. /* xtexcad  V1.2 - graphic editor for LaTeX */
  2. /* 1991 by K.Zitzmann */
  3. /* file_sel.c */
  4.  
  5.  
  6. #define MAXPATH LAENGE+LAENGE2   /* Laenge mit Pfad */ 
  7. #define LAENGE 21                /* Laenge Dateiname */
  8. #define WEITE 150                /* Breite des Directoryfensters */
  9. #define LAENGE2 50               /* Laenge Pfadname */
  10. #define HOEHE 300                /* Hoehe des Directoryfensters */
  11. #define ABSTAND 8                /* Abstand zwischen den einzelnen Widgets */
  12. #define DEFAULT_X 300            /* Vorgabe fuer X Koordinate */
  13. #define DEFAULT_Y 300            /* Vorgabe fuer Y Koordinate */
  14.  
  15. #include <strings.h>
  16. #include <sys/types.h>
  17. #include <sys/param.h>
  18. #include <sys/dir.h>
  19. #include <sys/stat.h>
  20. #include <X11/IntrinsicP.h>
  21. #include <X11/Shell.h>
  22. #include <X11/ShellP.h>
  23. #include <X11/Xaw/Viewport.h>
  24. #include <X11/Xaw/DialogP.h>
  25. /* R4: */
  26. /* #include <X11/Xaw/AsciiSrc.h> */
  27. /* R5 */
  28. #include <X11/Xaw/AsciiText.h>
  29.  
  30. #include <X11/Xaw/Text.h>
  31.  
  32. #include "extdef.h"
  33. #include "x_stuff.h"
  34. #include "file_sel.h"
  35.  
  36.  
  37. static char *filename;                    /* Pointer auf Filename */
  38. static Widget file_s;                     /* Popupshell fuer Fileselectbox */
  39. static Widget list_direct,                /* Directoryeintraege im Fenster */
  40.           titel_zeile;                /*Label fuer angezeigte Titelzeile */
  41.  
  42. static DialogWidget path,                 /* Dialog fuer Ausgabe Path */
  43.             text,                 /* Eingabe Filename DialogWidget */
  44.             patt_t;               /* Labelfeld Ausgabe des Patterns */
  45.  
  46. static char _default[LAENGE];             /* String zum Loeschen des Labels */
  47. static char _default2[LAENGE2];           /* String zum Loesch Titel,Path */
  48. static char patt_global[LAENGE];          /* Pattern als globale Variable */
  49. static int init_called=0;                 /* Widgets korrekt mit INIT_FILE_ */
  50.                       /* SELECT initialisiert */
  51.  
  52. /* Pointer werden global benoetigt um Speicher beim Verlassen der Fileselect-*/
  53. /* box wieder freigegeben werden kann */
  54. static String *Liste;                     /* Liste der bearbeiteten Strings */
  55. static char *Inhalt;                      /* Listeninhalt */ 
  56.  
  57. static char *getcwd(buf,size)
  58. char *buf;
  59. int size;
  60. {
  61. char pathname[MAXPATHLEN];
  62.  
  63. getwd(pathname);
  64. pathname[size-1] = '\0';
  65. strncpy(buf,pathname,size);
  66. }
  67.  
  68. /*****************************************************************************/
  69. /* Funktion ueberprueft, ob uebergebener Name ein Directory oder eine Datei  */
  70. /* ist.                                                                      */
  71. /*                                                                           */
  72. /* Aufruf: Is_direct(name);                                                  */
  73. /*                                                                           */
  74. /* Parameter: char *name; Name der Datei, die als Directory getestet werden  */
  75. /*                        soll.                                              */
  76. /* Rueckgabe: int;  0 Uebergebener Name war kein Directory, oder Name war    */
  77. /*                    ueberhaupt kein Eintrag in dem aktuellen Directory, der*/
  78. /*                    opendir() zu oeffnen war.                              */
  79. /*                  1 Uebergebener Name war Directory                        */
  80. /*****************************************************************************/
  81. int Is_direct(name)
  82.     char *name;
  83. {
  84.     struct stat buf;
  85.  
  86.     stat(name,&buf);         
  87.      
  88.     if(buf.st_mode & S_IFDIR)
  89.         return(1);              
  90.     else
  91.         return(0);
  92. }
  93.  
  94. /*****************************************************************************/
  95. /* Funktion zaehlt Eintrage im aktuellen Verzeichnis, die zum Pattern passen */
  96. /* oder ein Directoryeintrag sind.                                           */
  97. /*                                                                           */
  98. /* Aufruf: count_eintraege();                                                */
  99. /*                                                                           */
  100. /* Parameter: keine;                                                         */
  101. /* Rueckgabe: short; Anzahl der Eintraege im Directory, die der Bedingung    */
  102. /*                   genuegt haben.                                          */
  103. /*****************************************************************************/
  104. short count_eintraege()
  105. {
  106.    DIR *dirp;                      /* offenes Directory */
  107.    struct direct *datei;           /* gelesenener Directoryeintrag */
  108.    short counter=0;                
  109.  
  110.    dirp = opendir(".");
  111.    while((datei = readdir(dirp)) != NULL)
  112.      if((match(datei->d_name,patt_global)) || (Is_direct(datei->d_name)))
  113.      counter ++;
  114.  
  115.    closedir(dirp);
  116.    return(counter);
  117. }
  118.   
  119. /*****************************************************************************/
  120. /* Funktion ueberprueft, ob uebergeneber String zu dem uebergebenen Pattern  */
  121. /* passt.                                                                    */
  122. /*                                                                           */
  123. /* Aufruf: match(string,pattern);                                            */
  124. /*                                                                           */
  125. /* Parameter: char *string; String, der uenerprueft werden soll              */
  126. /*            char *pattern; Pattern mit dem der Striong verglichen wird     */
  127. /* Rueckgabe: 0 String passt nicht zu dem uebergebenen Pattern               */
  128. /*            1 String passt zu dem ubergebenen Pattern                      */
  129. /*****************************************************************************/
  130. int match(sstring,pattern)
  131. char *sstring,*pattern;
  132. {
  133.      char *st,*pa;
  134.      int lst=0,lpa=0,ist=1,ipa=1;
  135.  
  136.      st=sstring; while (*st++) lst++; st=sstring; /* Laenge berechnen */
  137.      pa=pattern;while (*pa++) lpa++; pa=pattern;/* Laenge berechnen */
  138.      if (!(lst*lpa)) return(0);     /* Ein String war leer */
  139.  
  140.      while(1)
  141.       {
  142.       if (*pa == '?')
  143.            {
  144.            if (ist>lst) return(0);
  145.            ++ist; ++st; ++ipa; ++pa;
  146.            if ((ist>lst) && (ipa>lpa)) return(1);
  147.            if (ipa>lpa) return(0);
  148.            continue;
  149.            }
  150.       if (*pa == '*')
  151.            {
  152.            if (ipa == lpa) return(1);
  153.            ++ipa; ++pa;
  154.            if (ist > lst) continue;
  155.            do
  156.             {
  157.             if (match(st,pa)) return(1);
  158.             ++ist; ++st;
  159.             } while (ist <= lst);
  160.            return(0);
  161.            }
  162.       if ((ist > lst) || (!(*st++ == *pa++))) return(0);
  163.       ++ipa;
  164.       if ((++ist > lst) && (ipa > lpa)) return(1);
  165.       } /* von while */
  166. } /* von match */
  167.  
  168. /*****************************************************************************/
  169. /* Funktion erstellt aus allen passenden Eintraegen im Directory eine Liste, */
  170. /* die an das Listwidget uebergeben werden kann.                             */
  171. /*                                                                           */
  172. /* Aufruf: directory_erstellen(anzahl);                                      */
  173. /*                                                                           */
  174. /* Parameter: short anzahl; anzahl der Eintraege, die in die Liste eingefuegt*/
  175. /*                          werden, um Speicher zu allocieren.               */
  176. /* Rueckgabe: String *; Pointer auf den Listenkopf                           */
  177. /*****************************************************************************/
  178. String *directory_erstellen(short anzahl)
  179.  {
  180.    static char *offset;            /* Naechste freie Speicherstelle */
  181.    static DIR *dirp2;              /* offenes Directory */
  182.    struct direct *datei;           /* Struktur um Dateinamen zu ermitteln */
  183.    short i=0;                      /* Zaehler */                     
  184.    char f_name[LAENGE];            /* Filename in passender Laenge */
  185.    char *eintrag;                  /* Rueckgabe des geprueften Eintrages */
  186.    String *Liste2;                 /* Liste der bearbeiteten Strings */
  187.    char *Inhalt2;                  /* Listeninhalt */ 
  188.    short directory_typ;            /* Eintrag ist Directory */
  189.    char *stelle;                   /* temp Pointer */
  190.  
  191.    /* neuen Speicher suchen */
  192.    Liste2 = (String *)malloc((anzahl+2)*sizeof(Liste));
  193.    Inhalt2 = offset = (char *)malloc((anzahl+1)*(LAENGE+1)*sizeof(char));
  194.  
  195.    /* aktuelles Verzeichnis oeffnen */
  196.    dirp2 = opendir(".");
  197.  
  198.    directory_typ = 0;
  199.     
  200.    /* Directoryeintraege in Liste uebernehmen */
  201.    i = 0;
  202.    while((datei = readdir(dirp2)) != NULL)
  203.      /* Eintrag ueberpruefen mit match-Funktion und ueberpruefen ob Direct. */
  204.      if((directory_typ = Is_direct(datei->d_name)) ||
  205.        (match(datei->d_name,patt_global)))
  206.          {
  207.      sprintf(f_name,"%-20.20s",datei->d_name);
  208.  
  209.      /* falls Namen zu lang letzte Stelle mit Stern ausgeben */
  210.      if((stelle=index(f_name,' ')) == NULL)  
  211.        {
  212.        f_name[LAENGE] = '\0';
  213.        f_name[LAENGE-1] = '*';
  214.        }
  215.      if(directory_typ)  /* Directorys wird zur Kennung ein / angehangen */
  216.        {
  217.          /* nachfolgende Blanks abschneiden */
  218.          if((stelle=index(f_name,' ')) != NULL)  
  219.            *stelle = '/';
  220.          else 
  221.            {
  222.            f_name[LAENGE-1] = '/';
  223.            f_name[LAENGE-2] = '*';
  224.            }
  225.        }
  226.      strcpy(offset,f_name);              /* Stringinhalt uebernehmen */
  227.      Liste2[i] = (char *)offset;         /* String in Liste anfuegen */
  228.      offset = (char *)(offset + LAENGE);  /* freie Stelle */
  229.      i++;
  230.      }
  231.    
  232.    /* Liste alphabetisch sortieren */
  233.    qsort(Liste2[2],i-2,LAENGE,strcmp);
  234.    
  235.    /* Liste mit NULL Eintrag beenden */
  236.    i++;
  237.    Liste2[i] = NULL;
  238.  
  239.    /* Directory Stream schliessen */
  240.    closedir(dirp2);
  241.  
  242.    /* alten Speicher wieder freigeben */
  243.    if(Liste != NULL)
  244.      free(Liste);
  245.    if(Inhalt != NULL)
  246.      free(Inhalt);
  247.  
  248.    Liste = Liste2;
  249.    Inhalt = Inhalt2;
  250.  
  251.    return((String *)Liste); /* Pointer auf Listenkopf wird zureuckgegeben */
  252. }
  253.  
  254. /*****************************************************************************/
  255. /* Funktion steuert bei einer Neuerstellung der Liste im Listwidget den      */
  256. /* Ablauf und veranlasst die sich daraus ergebenden Folgen.                  */
  257. /*                                                                           */
  258. /* Aufruf: direct_to_list();                                                 */
  259. /*                                                                           */
  260. /* Parameter: keine                                                          */
  261. /* Rueckgabe: keine                                                          */
  262. /*****************************************************************************/
  263. void direct_to_list()
  264. {
  265.    Arg args[1];
  266.    short anzahl;              /* anzahl Directoryeintraege */
  267.  
  268.    anzahl = count_eintraege();
  269.  
  270.    /* Datei bei einem Patternwechsel nicht mehr vorhanden */
  271.    /* Dateinamen in Labelfeld loeschen */
  272.    /* ohne direkt in Pointer zu schreiben wird Wert nicht angezeigt */
  273.    XtSetArg(args[0],XtNstring," ");
  274.    XtSetValues(((DialogWidget)text)->dialog.valueW,args,1);
  275.  
  276.    /* neue Liste erstellen und Listwidget uebergeben */
  277.    XtUnmanageChild(list_direct);
  278.    XawListChange(list_direct,directory_erstellen(anzahl),anzahl,0,True);
  279.    XtManageChild(list_direct);
  280.  
  281.    /* Rollbalken wieder am oeberen Ende positionieren */ 
  282.  
  283.  
  284. }        
  285.  
  286. /*****************************************************************************/
  287. /* Callbackfunktion fuer den Ok-Button. (Rueckgabe Dateiname, Fileselectbox  */
  288. /* schliessen.                                                               */
  289. /*                                                                           */
  290. /* Aufruf: Ok_gelickt(w,client_data,call_data);                              */
  291. /*                                                                           */
  292. /* Funktion wird nur von X-Windows aufgerufen.                               */
  293. /*****************************************************************************/
  294. void Ok_geklickt(Widget w ,caddr_t client_data,caddr_t call_data)
  295. {
  296.   char *stelle;                 /* Pointer auf erstes Blank im String */
  297.  
  298.  
  299.   if(XawDialogGetValueString(text)[0]  == ' ')
  300.     /* falls Dateiname leer ist wird NULL zurueck gegeben vgl. CANCEL-Button */
  301.     filename = NULL;
  302.   else 
  303.     {
  304.     /* Dateinamenfeld war mit Dateinamen gefuellt */
  305.     filename = (char *)malloc(MAXPATH*sizeof(char));
  306.     getcwd(filename,LAENGE2);
  307.     strcat(filename,"/");
  308.     strcat(filename,XawDialogGetValueString(text));
  309.     /* nachfolgende Blanks abschneiden */
  310.     if((stelle=index(filename,' ')) != NULL)  
  311.     *stelle = '\0';
  312.     }
  313.  
  314.   /* Ueberpruefen, ob Dateiname jetzt tatsaechlich passt */
  315.   free(Liste);
  316.   free(Inhalt);
  317.   XtPopdown(file_s);             /* Ruecksprung */
  318. }
  319.  
  320. /*****************************************************************************/
  321. /* Callbackfunktion fuer den Return im Labelfeld Dateinamen aufgerufen       */
  322. /* Setzt die Parmeter fuer Ok_geklickt (s.o.) um.                            */
  323. /*                                                                           */
  324. /* Aufruf: Ok2_gelickt(widget,event,params,n_params);                        */
  325. /*                                                                           */
  326. /* Funktion wird nur von X-Windows aufgerufen.                               */
  327. /*****************************************************************************/
  328. void Ok2_geklickt(Widget widget,XEvent *event,String *params,Cardinal *n_params)
  329. {
  330.   /* Prozedur wird nach <Return> in Labelfeld aufgerufen */
  331.   /* setzt nur Parameter fuer Ok_geklickt um */
  332.   Ok_geklickt(XtParent(widget),NULL,NULL);
  333. }
  334.  
  335.  
  336. /*****************************************************************************/
  337. /* Callbackfunktion fuer den Return im Labelfeld Pfadnamen aufgerufen        */
  338. /* Wechselt in neuen Pfad und erstellt Eintraege in der Liste neu.           */
  339. /*                                                                           */
  340. /* Aufruf: Path_changed(widget,event,params,n_params);                       */
  341. /*                                                                           */
  342. /* Funktion wird nur von X-Windows aufgerufen.                               */
  343. /*****************************************************************************/
  344. void Path_changed(Widget widget,XEvent *event,String *params,Cardinal *n_params)
  345. {
  346.   char *home,               /* Homedirectory aus dem Environment */
  347.        *stelle;             /* temporaerer Pointer */
  348.   char p_name[LAENGE2];     /* Pfad in korrigierter Laenge */
  349. char p_name2[LAENGE2];
  350.   char neuer_pfad[LAENGE2]; /* neuer eingegebene Pfad */
  351. Arg args[1];
  352.   
  353.   /* Prozedur wird nach <Return> in Dialogfeld fuer Path aufgerufen */
  354.   /* uebernimmt ggf. neues Pattern und aendert Eintrage im Fenster    */
  355.   sprintf(neuer_pfad,"%-50.50s",XawDialogGetValueString(XtParent(widget)));
  356.   /* nachfolgende Blanks abschneiden */
  357.  
  358.   if((stelle=index(neuer_pfad,' ')) != NULL)  
  359.     *stelle = '\0';
  360.   else                       /* Namen sind zu lang */ 
  361.     {
  362.     neuer_pfad[LAENGE2] = '\0';
  363.     neuer_pfad[LAENGE2-1] = '*';
  364.     }
  365.  
  366.   if(chdir(neuer_pfad) == -1)
  367.     /* Fehler beim Wechsel in angegebenen Pfadnamen */
  368.     {
  369.     home = getenv("HOME");
  370.     if(home != NULL)
  371.        chdir(home);    /* bei Fehler ins Homedirectory wechseln */ 
  372.     else               /* kein Eintrag fuer Homedirectory gefunden */
  373.        chdir("/");
  374.  
  375.     /* Dialogfeld zur Ausgabe des aktuellen Verzeichnisnamen  aendern  */
  376.     getcwd(p_name,LAENGE2);
  377.     /* ohne direkt in Pointer zu schreiben wird Wert nicht angezeigt */
  378.     XtSetArg(args[0],XtNstring,p_name);
  379.     XtSetValues(((DialogWidget)path)->dialog.valueW,args,1);
  380.     }
  381.  
  382.   /* evtl. Wechsel in neues Directory erfolgt, daher Liste neu erstellen */
  383.   direct_to_list();
  384. }
  385.  
  386. /*****************************************************************************/
  387. /* Callbackfunktion fuer ein Verlassen des Labelfeldes fuer Pfadeingabe      */
  388. /* wenn die Eingabe des Pfades nichtr mit Return abgeschlossen wurde, so     */
  389. /* muss der Pfad wieder korrekt angezeigt werden.                            */
  390. /*                                                                           */
  391. /* Aufruf: Path_leave(widget,event,params,n_params);                         */
  392. /*                                                                           */
  393. /* Funktion wird nur von X-Windows aufgerufen.                               */
  394. /*****************************************************************************/
  395. void Path_leave(Widget widget,XEvent *event,String *params,Cardinal *n_params)
  396. {
  397.   char p_name[LAENGE2];     /* Pfad in korrigierter Laenge */
  398. char p_name2[LAENGE2];
  399. Arg args[1];
  400.  
  401.   /* Dialogfeld zur Ausgabe des aktuellen Verzeichnisnamen  aendern  */
  402.   getcwd(p_name,LAENGE2);
  403.   /* ohne direkt in Pointer zu schreiben wird Wert nicht angezeigt */
  404.   sprintf(p_name2,"%-50.50s",p_name);
  405.   XtSetArg(args[0],XtNstring,p_name2);
  406.   XtSetValues(((DialogWidget)path)->dialog.valueW,args,1);
  407. }
  408.  
  409. /*****************************************************************************/
  410. /* Callbackfunktion fuer den Return im Labelfeld Pattern aufgerufen          */
  411. /* Wechselt globales Pattern aus und erstellt Eintrage in der Liste neu.     */
  412. /*                                                                           */
  413. /* Aufruf: Patt_changed(widget,event,params,n_params);                       */
  414. /*                                                                           */
  415. /* Funktion wird nur von X-Windows aufgerufen.                               */
  416. /*****************************************************************************/
  417. void Patt_change(Widget widget,XEvent *event,String *params,Cardinal *n_params)
  418. {
  419.   char neues_patt[LAENGE];   /* neues Patternmuster */
  420.  
  421.   /* Prozedur wird nach <Return> in Labelfeld fuer Pattern aufgerufen */
  422.   /* uebernimmt ggf. neues Pattern und aendert Eintrage im Fenster    */
  423.   strcpy(neues_patt,(char *)XawDialogGetValueString(XtParent(widget)));
  424.  
  425.   if(neues_patt != patt_global)       /* nur aendern falls Pattern anders */
  426.     {
  427.     strcpy(patt_global,neues_patt);   /* neues Pattern setzen */
  428.     /* Eintrage im Fenster neu erstellen */ 
  429.     direct_to_list();
  430.     }
  431. }
  432.  
  433. /*****************************************************************************/
  434. /* Callbackfunktion fuer den Cancel-Button.(Rueckgabe NULL, Fileselectbox    */
  435. /* schliessen.                                                               */
  436. /*                                                                           */
  437. /* Aufruf: Cancel_gelickt(w,client_data,call_data);                          */
  438. /*                                                                           */
  439. /* Funktion wird nur von X-Windows aufgerufen.                               */
  440. /*****************************************************************************/
  441. void Cancel_geklickt(Widget w,caddr_t client_data,caddr_t call_data)
  442. {
  443.   filename = NULL;                  /* gibt immer NULL zurueck */
  444.   free(Liste);
  445.   free(Inhalt);
  446.   XtPopdown(file_s);
  447. }
  448.  
  449. /*****************************************************************************/
  450. /* Callbackfunktion fuer das Waehlen eines Eintrages in der Liste des List-  */
  451. /* widget. Prueft, ob Name eine Datei (Uebernahme in Dialogewidget) oder ein */
  452. /* Directory ist. (Wechsel in neues Directory,Liste neu erstellen)           */
  453. /*                                                                           */
  454. /* Aufruf: File_gewaehlt(w,client_data,call_data);                           */
  455. /*                                                                           */
  456. /* Funktion wird nur von X-Windows aufgerufen.                               */
  457. /*****************************************************************************/
  458. void File_gewaehlt(Widget w,caddr_t client_data,caddr_t call_data)
  459. {
  460.   char name[LAENGE+2],          /* gekuerzter Eintragsnamen (ohne Blanks) */
  461.        p_name[LAENGE2],         /* Pathname mit 50 Stellen */
  462.        p_name2[LAENGE2];
  463. char name2[21];
  464.   Arg args[1];                  /* Argumentvektor */
  465.   char *stelle;                 /* Pointer auf erstes Blank im String */
  466.   short i;                      /* Zaehler */
  467.   XawListReturnStruct *feld;     /* Rueckgabe gewaehltes Feld(Listwidget) */
  468.  
  469.   
  470.   /* geklickter Dateinamen ermitteln */
  471.   feld = XawListShowCurrent(w);  
  472.  
  473.   /* Zeichenkette kopieren, damit Button nicht veraendert wird */
  474.   strcpy(name,feld->string); 
  475.   name[LAENGE+2] = '\0';
  476.  
  477.   /* nachfolgende Blanks abschneiden */
  478.   if((stelle=index(name,' ')) != NULL)  
  479.     *stelle = '\0';
  480.  
  481.   if (!(Is_direct(name)) && (name[0] != ' ')) /* Name nicht leer */
  482.      /* Eintrag war Dateieintrag */
  483.      {
  484.      /* Eintrag wird in Labelfeld uebernommen */
  485.      /* ohne direkt in Pointer zu schreiben wird der Wert nicht angezeigt */
  486.      sprintf(name2,"%-20s",name);
  487.      XtSetArg(args[0],XtNstring,name2);
  488.      XtSetValues(((DialogWidget)text)->dialog.valueW,args,1);
  489.      }
  490.   else                                          
  491.      {
  492.      /* Eintrag war Directory */
  493.      chdir(name);
  494.  
  495.      /* Dialogfeld zur Ausgabe des aktuellen Verzeichnisnamen  aendern  */
  496.      getcwd(p_name,LAENGE2);
  497.      /* ohne direkt in Pointer zu schreiben wird Wert nicht angezeigt */
  498.      sprintf(p_name2,"%-50.50s",p_name);
  499.      XtSetArg(args[0],XtNstring,p_name2);
  500.      XtSetValues(((DialogWidget)path)->dialog.valueW,args,1);
  501.  
  502.      /* neue Liste erstellen und anzeigen */
  503.      direct_to_list();
  504.  
  505.      }
  506.  
  507.  
  508.  
  509. /*****************************************************************************/
  510. /* Funktion setzt einen String die Mitte eines Strings, der aus einer ueber- */
  511. /* gebenen Anzahl von Leerzeichen besteht.                                   */
  512. /*                                                                           */
  513. /* Aufruf: center(zeile,laenge);                                             */
  514. /*                                                                           */
  515. /* Parameter: char *zeile; String der positioniert werden soll.              */
  516. /*            short laenge; Laenge des neu erstellten Strings.               */
  517. /* Rueckgabe: char *; Pointer auf den neu erstellten String                  */
  518. /*                                                                           */
  519. /* !Vorsicht: der Speicher fuer den neuen String wird mit malloc belegt und! */
  520. /* !sollte daher vom spaeteren Benutzer wieder freigegeben werden          ! */
  521. /*****************************************************************************/
  522. char *center(char *zeile,short laenge)
  523. {
  524.    char *neue_zeile;            /* neu erstellter String */
  525.    short blanks,                /* Anzahl fuehrende Blanks */
  526.      zeilen_laenge,         /* Laenge des uebergebenen Strings */
  527.      i,s;
  528.  
  529.    zeilen_laenge = strlen(zeile);
  530.    neue_zeile = (char *)malloc((laenge+1) *sizeof(char));
  531.  
  532.    /* am Anfang Blanks einfuegen */
  533.    blanks = (int)((laenge - zeilen_laenge)/2);
  534.  
  535.    /* gesamten String loeschen */
  536.    for(i=0;i<=laenge;i++)
  537.       neue_zeile[i] = ' ';
  538.  
  539.    /* String uebernehmen */
  540.    for(i=blanks;i<=blanks+zeilen_laenge-1;i++)
  541.       neue_zeile[i] = zeile[i-blanks];
  542.     
  543.    neue_zeile[laenge] = '\0';
  544.             
  545.    return(neue_zeile);
  546. }
  547.  
  548. /*****************************************************************************/
  549. /* Callbackfunktion fuer allgemeine Events die unterdreuckt werden sollen    */
  550. /* Die Funktion wird aufgerufen, raeumt den Stack auf und kehrt zureuck      */
  551. /*                                                                           */
  552. /* Aufruf: Dummy(widget,event,params,n_params);                              */
  553. /*                                                                           */
  554. /* Funktion wird nur von X-Windows aufgerufen.                               */
  555. /*****************************************************************************/
  556. /* Prozedur dient dazu unerwuenscht Events abzufangen */
  557. void Dummy(Widget widget,XEvent *event,String *params,Cardinal *n_params)
  558. {
  559. }
  560.  
  561. /*****************************************************************************/
  562. /* Funktion initialisiert Fileselectbox.(erstellt Widgets usw.)              */
  563. /* Diese Funktion wird i.A. nur einmal waehrend eines Programmes aufgerufen  */
  564. /*                                                                           */
  565. /* Aufruf: init_file_select(w);                                              */
  566. /*                                                                           */
  567. /* Parameter: Widget w; Widget im Baum, an das Fileselectbox gehangen wird   */
  568. /* Rueckgabe: PopupShell Widget, dass Fileselectbox Popup enthaelt           */
  569. /*****************************************************************************/
  570. Widget init_file_select(Widget w)     
  571. {
  572.    Arg args[8];               /* Argumentvektor */
  573.    Widget ok,                 /* Button fuer Ok */
  574.       box,                /* Rahmen um ganze Fileselectbox */
  575.       fenster,            /* ViewportWidget um Dir-Eintraege */
  576.       cancel;             /* Button fuer Cancel */
  577.    short anzahl;              /* Anzahl temporaere Variablen */
  578.    XtTranslations trans;      /* Aktionsbeschreibung */
  579.    /* hinzugefuegte Events bei den Dialogboxen */
  580.    static XtActionsRec Return_null[]={{"Ok2_geklickt",Ok2_geklickt},};
  581.    static XtActionsRec Patt_return[]={{"Patt_change",Patt_change},};
  582.    static XtActionsRec Dummy_call[]={{"Dummy",Dummy},};
  583.    static XtActionsRec Path_return[]={{"Path_changed",Path_changed},};
  584.    static XtActionsRec Path_verlas[]={{"Path_leave",Path_leave},};
  585.    
  586.    Dimension breite;
  587.  
  588.    /* Abfrage, so dass FileSelectbox nur einmal initialisiert wird */
  589.    if(init_called)  /* bereits aufgerufen */
  590.      return(file_s);
  591.  
  592.    /* Funktion zum ersten mal aufgerufen Flag setzen */ 
  593.    init_called = 1;                   
  594.  
  595.    /* Pattern initialisieren */
  596.    strcpy(patt_global,"*");
  597.  
  598.    /* Voreinstellung fuer Dateiname ist Leerstrings */
  599.    sprintf(_default,"%-21s"," ");
  600.    sprintf(_default2,"%-51s"," ");
  601.  
  602.    /* File_selectbox ist Popupshell */
  603.    XtSetArg( args[0],XtNx, (XtArgVal) DEFAULT_X);
  604.    XtSetArg( args[1],XtNy, (XtArgVal) DEFAULT_Y);
  605.    file_s = XtCreatePopupShell("F1",transientShellWidgetClass,w,args,2);
  606.    
  607.    /* passender Rahmen um das Ganze */
  608.    box = XtCreateManagedWidget("F2",formWidgetClass,file_s,NULL,0);
  609.  
  610.    /* Labelfeld zur Ausgabe der Ueberschrift */           
  611.    XtSetArg( args[0],XtNlabel, (XtArgVal) _default2);
  612.    XtSetArg( args[1],XtNborderWidth, (XtArgVal) 4);
  613.    XtSetArg( args[2],XtNvertDistance, (XtArgVal) ABSTAND);
  614.    XtSetArg( args[3],XtNhorizDistance, (XtArgVal) ABSTAND);
  615.    titel_zeile = XtCreateManagedWidget("F10",labelWidgetClass,box,args,4);
  616.    
  617.    /* Dialogfeld zur Ausgabe des aktuellen Verzeichnisnamen */
  618.    XtSetArg( args[0],XtNvalue, (XtArgVal) _default2);
  619.    XtSetArg( args[1],XtNvertDistance, (XtArgVal) ABSTAND);
  620.    XtSetArg( args[2],XtNhorizDistance, (XtArgVal) ABSTAND);
  621.    XtSetArg( args[3],XtNfromVert, (XtArgVal) titel_zeile);
  622.    XtSetArg( args[4],XtNlabel,(XtArgVal) _default2);
  623.    XtSetArg( args[5],XtNborderWidth, (XtArgVal) 0);       
  624.    path = (DialogWidget)
  625.     XtCreateManagedWidget("F9",dialogWidgetClass,box,args,6); 
  626.    /* Labelfeld bei der Dialogbox nicht auf den Bildschirm */
  627.    XtSetArg( args[0],XtNfromHoriz,(XtArgVal) NULL);
  628.    XtSetArg( args[1],XtNfromVert, (XtArgVal) NULL);
  629.    XtSetValues( path->dialog.valueW,args,2);
  630.    XtUnmanageChild(path->dialog.labelW);
  631.    XtSetArg(args[0],XtNwidth,&breite);
  632.    XtGetValues(path->dialog.labelW,args,1);
  633.    XtSetArg(args[0],XtNresize, XawtextResizeNever);
  634.    XtSetArg(args[1],XtNwidth,breite);
  635.    XtSetValues(path->dialog.valueW,args,2);
  636.    /* Return innerhalb des Textfeldes abfangen */
  637.    XtAppAddActions(XtWidgetToApplicationContext(path->dialog.valueW),
  638.       Path_return,1);
  639.    XtSetArg(args[0],XtNresize, XawtextResizeNever);
  640.    XtSetValues(((DialogWidget)path)->dialog.valueW,args,1);
  641.    trans=XtParseTranslationTable(":<Key>Return:Path_changed()");
  642.    XtOverrideTranslations(path->dialog.valueW,trans);
  643.    /* Eingabe von Leerzeichen im Filenamen ist verboten */
  644.    XtAppAddActions(XtWidgetToApplicationContext(path->dialog.valueW),
  645.       Dummy_call,1);
  646.    trans=XtParseTranslationTable(":<Key>space:Dummy()");
  647.    XtOverrideTranslations(path->dialog.valueW,trans);
  648.    /* Wenn das Dialogfeld ohne Return verlassen wird, so muss der */
  649.    /* Pfadname wieder korrekt angezeigt werden */
  650.    XtAppAddActions(XtWidgetToApplicationContext(path->dialog.valueW),
  651.       Path_verlas,1);
  652.    trans=XtParseTranslationTable(":<LeaveWindow>:Path_leave()");
  653.    XtAugmentTranslations(path->dialog.valueW,trans);
  654.  
  655.    /* Viewport um automatischen Rollbalken zu erzeugen */
  656.    XtSetArg( args[0],XtNallowVert, (XtArgVal) True);
  657.    XtSetArg( args[1],XtNheight, (XtArgVal) HOEHE);
  658.    XtSetArg( args[2],XtNwidth, (XtArgVal) WEITE);
  659.    XtSetArg( args[3],XtNforceBars, (XtArgVal) True);
  660.    XtSetArg( args[4],XtNfromVert, (XtArgVal) path);
  661.    XtSetArg( args[5],XtNvertDistance, (XtArgVal) ABSTAND);
  662.    XtSetArg( args[6],XtNhorizDistance, (XtArgVal) ABSTAND);
  663.    fenster =XtCreateManagedWidget("F3",viewportWidgetClass,box,args,7);
  664.   
  665.    /* Directoryeintraege in ListWidget uebernehmen */
  666.    anzahl = count_eintraege();
  667.    XtSetArg( args[0],XtNverticalList, (XtArgVal) True);
  668.    XtSetArg( args[1],XtNlist, (XtArgVal) directory_erstellen(anzahl));
  669.    XtSetArg( args[2],XtNnumberStrings, (XtArgVal) anzahl);
  670.    XtSetArg( args[3],XtNlongest, (XtArgVal) WEITE);
  671.    XtSetArg( args[4],XtNwidth, (XtArgVal) WEITE);
  672.    XtSetArg( args[5],XtNvertDistance, (XtArgVal) ABSTAND);
  673.    list_direct = XtCreateManagedWidget("F5",listWidgetClass,fenster,args,6);
  674.    XtAddCallback(list_direct,XtNcallback,File_gewaehlt,NULL);
  675.  
  676.    /* Eingabefeld fuer Dateinamen */
  677.    XtSetArg( args[0],XtNlabel, (XtArgVal) "    FILENAME <cr>   ");
  678.    XtSetArg( args[1],XtNvalue, (XtArgVal) _default);
  679.    XtSetArg( args[2],XtNvertDistance, (XtArgVal) (3*ABSTAND));
  680.    XtSetArg( args[3],XtNfromVert, (XtArgVal) path);
  681.    XtSetArg( args[4],XtNhorizDistance, (XtArgVal) (2*ABSTAND));
  682.    XtSetArg( args[5],XtNfromHoriz, (XtArgVal) fenster);
  683.    text =(DialogWidget)
  684.      XtCreateManagedWidget("F6",dialogWidgetClass,box,args,6);
  685.    XtSetArg(args[0],XtNwidth,&breite);
  686.    XtGetValues(text->dialog.labelW,args,1);
  687.    XtSetArg(args[0],XtNresize, XawtextResizeNever);
  688.    XtSetArg(args[1],XtNwidth,breite);
  689.    XtSetValues(text->dialog.valueW,args,2);
  690.    XtSetArg(args[0],XtNresize, XawtextResizeNever);
  691.    XtSetValues(((DialogWidget)text)->dialog.valueW,args,1);
  692.  
  693.    /* Return abfangen */
  694.    XtAppAddActions(XtWidgetToApplicationContext(text->dialog.valueW),
  695.       Return_null,1);
  696.    trans=XtParseTranslationTable(":<Key>Return:Ok2_geklickt()");
  697.    XtOverrideTranslations(text->dialog.valueW,trans);
  698.    /* Eingabe von Leerzeichen im Filenamen ist verboten */
  699.    XtAppAddActions(XtWidgetToApplicationContext(text->dialog.valueW),
  700.       Dummy_call,1);
  701.    trans=XtParseTranslationTable(":<Key>space:Dummy()");
  702.    XtOverrideTranslations(text->dialog.valueW,trans);
  703.  
  704.    /* Eingabefeld fuer Pattern */
  705.    XtSetArg( args[0],XtNlabel, (XtArgVal) "    FILETYPE <cr>   ");
  706.    XtSetArg( args[1],XtNvalue, (XtArgVal) _default);
  707.    XtSetArg( args[2],XtNvertDistance, (XtArgVal) ABSTAND);
  708.    XtSetArg( args[3],XtNfromVert, (XtArgVal) text);
  709.    XtSetArg( args[4],XtNhorizDistance, (XtArgVal) (2*ABSTAND));
  710.    XtSetArg( args[5],XtNfromHoriz, (XtArgVal) fenster);
  711.    patt_t=(DialogWidget)    
  712.      XtCreateManagedWidget("F13",dialogWidgetClass,box,args,6);
  713.    XtSetArg(args[0],XtNwidth,&breite);
  714.    XtGetValues(patt_t->dialog.labelW,args,1);
  715.    XtSetArg(args[0],XtNresize, XawtextResizeNever);
  716.    XtSetArg(args[1],XtNwidth,breite);
  717.    XtSetValues(patt_t->dialog.valueW,args,2);
  718.    XtSetArg(args[0],XtNresize, XawtextResizeNever);
  719.    XtSetValues(((DialogWidget)patt_t)->dialog.valueW,args,1);
  720.    /* Return abfangen */
  721.    XtAppAddActions(XtWidgetToApplicationContext(patt_t->dialog.valueW),
  722.       Patt_return,1);
  723.    trans=XtParseTranslationTable(":<Key>Return:Patt_change()");
  724.    XtOverrideTranslations(patt_t->dialog.valueW,trans);
  725.    /* Eingabe von Leerzeichen im Pattern ist verboten */
  726.    XtAppAddActions(XtWidgetToApplicationContext(patt_t->dialog.valueW),
  727.       Dummy_call,1);
  728.    trans=XtParseTranslationTable(":<Key>space:Dummy()");
  729.    XtOverrideTranslations(patt_t->dialog.valueW,trans);
  730.  
  731.    /* Cancel Button */
  732.    XtSetArg( args[0],XtNlabel, (XtArgVal) "        Cancel         ");
  733.    XtSetArg( args[1],XtNvertDistance, (XtArgVal) (16*ABSTAND));
  734.    XtSetArg( args[2],XtNfromVert, (XtArgVal) patt_t);
  735.    XtSetArg( args[3],XtNhorizDistance, (XtArgVal) (2* ABSTAND));
  736.    XtSetArg( args[4],XtNfromHoriz, (XtArgVal) fenster);
  737.    cancel = XtCreateManagedWidget("F7",commandWidgetClass,box,args,5);
  738.    XtAddCallback(cancel,XtNcallback,Cancel_geklickt,NULL);
  739.  
  740.    /* OK Button */
  741.    XtSetArg( args[0],XtNlabel,(XtArgVal) "        Accept         ");
  742.    XtSetArg( args[1],XtNvertDistance, (XtArgVal) ABSTAND);
  743.    XtSetArg( args[2],XtNfromVert, (XtArgVal) cancel);
  744.    XtSetArg( args[3],XtNhorizDistance, (XtArgVal) (2*ABSTAND));
  745.    XtSetArg( args[4],XtNfromHoriz, (XtArgVal) fenster);
  746.    ok = XtCreateManagedWidget("F8",commandWidgetClass,box,args,5);
  747.    XtAddCallback(ok,XtNcallback,Ok_geklickt,NULL);
  748.  
  749.    return(file_s);
  750. }
  751.  
  752.  
  753. /*****************************************************************************/
  754. /* Funktion zum Aufruf der Fileselectbox.   (s.o)                            */
  755. /*                                                                           */
  756. /* Aufruf: File_select(x,y,patt,titel);                                      */
  757. /*****************************************************************************/
  758. char *file_select(char *patt,char *titel)
  759. {
  760.    XtAppContext app_context;           /* Applikationskontext */
  761.    XEvent event;                       /* Event */
  762.    Arg args[2];                        /* Argumentvektor */
  763.    char p_name[LAENGE2],               /* Path ion korrigierter Laenge */
  764.     t_name[LAENGE2];               /* Titel in korrigierter Laenge */
  765.    char *temp;                         /* Pointer zur Speicherfreigabe */
  766.  
  767.    if( strlen(patt) > LAENGE || 
  768.       strlen(titel) == 0 || strlen(titel) > LAENGE2 )
  769.       {
  770.  
  771.       printf("Die Argumente sind nicht korrekt !!! \n");
  772.       return(NULL);
  773.       }
  774.    else 
  775.       {
  776.  
  777.       Liste = (String *)NULL;
  778.       Inhalt = (char *)NULL;
  779.  
  780.       /* uebergebenes Pattern in globale Variable uebernehmen */
  781.       if(strlen(patt)!=0)
  782.           strcpy(patt_global,patt);
  783.       
  784.       /* Titelzeile in Labelfeld uebernehmen */
  785.       temp = center(titel,LAENGE2);  /* Ueberschrift zentrieren */
  786.       strcpy(t_name,temp);
  787.       free(temp);
  788.       XtSetArg( args[0],XtNlabel,(XtArgVal) t_name);
  789.       XtSetValues(titel_zeile,args,1);
  790.  
  791.       /* aktuellen Pfadnamen im Dialogwidget anzeigen */
  792.       temp = malloc(LAENGE2+1);
  793.       getcwd(temp,LAENGE2);
  794.       sprintf(p_name,"%-51s",temp);                        
  795.       free(temp);
  796.       /* Dialogfeld zur Ausgabe des aktuellen Verzeichnisnamen  aendern  */
  797.       /* ohne direkt in Pointer zu schreiben wird Wert nicht angezeigt */
  798.       XtSetArg(args[0],XtNstring,p_name);
  799.       XtSetValues(((DialogWidget)path)->dialog.valueW,args,1);
  800.  
  801.       /* Pattern in DialogWidget uebernehmen */
  802.       /* ohne direkt in Pointer zu schreiben wird Wert nicht angezeigt */
  803.       XtSetArg(args[0],XtNstring,patt_global);
  804.       XtSetValues(((DialogWidget)patt_t)->dialog.valueW,args,1);
  805.        
  806.       /* aktuelles Directory eintragen */
  807.       direct_to_list(); 
  808.  
  809.       /* Fileselectbox auf dem Bildschirm anzeigen */
  810.       XtPopup(file_s,XtGrabExclusive);
  811.        
  812.       /* Events im Popup selbst verwalten */
  813.       app_context = XtWidgetToApplicationContext(file_s);
  814.       while(((ShellWidget)file_s)->shell.popped_up)
  815.       {
  816.      XtAppNextEvent(app_context,&event);
  817.      XtDispatchEvent(&event);
  818.       }
  819.  
  820.       } 
  821.  
  822.    /* String bereits in beim OK-Button kontrolliert */
  823.    return(filename);
  824.  
  825.  
  826. /*******************************************************************
  827.  * Center a popup in the middle of another widget if possible,     *
  828.  * otherwise make shure that the popup is visible on the screen    *
  829.  *******************************************************************/
  830. void centerpopup(Widget centerin,Widget tocenter)
  831. {
  832. Display *CurDpy;
  833. Position xin,yin,x,y;
  834. Dimension win,hin,wto,hto;
  835. Arg args[4];
  836.  
  837. CurDpy = XtDisplay(centerin);
  838. XtRealizeWidget(tocenter);
  839. XtSetArg(args[0],XtNwidth,&wto);
  840. XtSetArg(args[1],XtNheight,&hto);
  841. XtGetValues(tocenter,args,2);
  842.  
  843. XtSetArg(args[0],XtNwidth,&win);
  844. XtSetArg(args[1],XtNheight,&hin);
  845. XtGetValues(centerin,args,2);
  846.  
  847. XtTranslateCoords(centerin,0,0,&xin,&yin);
  848.  
  849. x = xin + win/2 - wto/2;
  850. y = yin + hin/2 - hto/2;
  851. if(x < 0)
  852.     x = 0;
  853. if(y < 0)
  854.     y = 0;
  855. if((x+wto) > DisplayWidth(CurDpy, DefaultScreen(CurDpy)))
  856.     x = DisplayWidth(CurDpy, DefaultScreen(CurDpy)) - wto;
  857. if((y+hto) > DisplayHeight(CurDpy, DefaultScreen(CurDpy)))
  858.     y = DisplayHeight(CurDpy, DefaultScreen(CurDpy)) - hto;
  859.  
  860. XtSetArg(args[0],XtNx,x);
  861. XtSetArg(args[1],XtNy,y);
  862. XtSetValues(tocenter,args,2);
  863. XWarpPointer(CurDpy,None,DefaultRootWindow(CurDpy),0,0,0,0,x+wto/2,y+hto/2);
  864. }
  865.  
  866.